package me.atbar.moonlib.area;

import lombok.Getter;
import org.bukkit.Location;

/**
 * @author Administrator
 */
public abstract class BaseArea {

    @Getter
    private final Location min;
    @Getter
    private final Location max;

    protected BaseArea(BaseBuilder<?> builder) {
        this.min = builder.min;
        this.max = builder.max;
    }

    /**
     * 判断坐标是否含于该区域
     *
     * @param location 坐标
     */
    public boolean contain(Location location) {
        return location.getX() >= min.getX() && location.getY() >= min.getY() && location.getZ() >= min.getZ() &&
                location.getX() <= max.getX() && location.getY() <= max.getY() && location.getZ() <= max.getZ();
    }

    /**
     * 判断区域是否与该区域相交
     *
     * @param other 区域
     */
    public boolean intersect(final BaseArea other) {
        return max.getX() >= other.min.getX() && max.getY() >= other.min.getY() && max.getZ() >= other.min.getZ() &&
                min.getX() <= other.max.getX() && min.getY() <= other.max.getY() && min.getZ() <= other.max.getZ();
    }

    public abstract static class BaseBuilder<T> {

        @Getter
        private Location min;
        @Getter
        private Location max;

        public BaseBuilder(Location min, Location max) {
            this.min = min;
            this.max = max;
            double minX = min.getX(), minY = min.getY(), minZ = min.getZ();
            double maxX = max.getX(), maxY = max.getY(), maxZ = max.getZ();
            double t;
            if(minX > maxX) {
                t = minX;
                minX = maxX;
                maxX = t;
            }
            if(minY > maxY) {
                t = minY;
                minY = maxY;
                maxY = t;
            }
            if(minZ > maxZ) {
                t = minZ;
                minZ = maxZ;
                maxZ = t;
            }
            this.min = new Location(min.getWorld(), minX, minY, minZ);
            this.max = new Location(max.getWorld(), maxX, maxY, maxZ);
        }

        /**
         * 构建出一个具体的领地类
         *
         * @return 领地实现类
         */
        public abstract BaseArea build();

        /**
         * 返回具体Builder
         *
         * @return 构建器
         */
        protected abstract T self();

    }

}
